﻿#region 信息

// Copyright©2014 Rex Rao all rights reserved.
// File name : SoMcCoffee\Sohobloo.SoCommon\RangeExtension.cs
// Author : Sohobloo
// Create time : 2014/01/31 23:40
// Update time : 2014/02/05 8:54

#endregion

#region 引用

using System;

#endregion

namespace Sohobloo.SoCommon.CommonExtension
{
    public static class RangeExtension
    {
        /// <summary>
        ///     限制范围，value在边界中则返回value，否则返回边界值。
        ///     左右边界可以反向，区别在于当value为null时返回的是左边界。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="leftBoundary"></param>
        /// <param name="rightBoundary"></param>
        /// <returns></returns>
        public static T RestrictBetween<T>(this T value, T leftBoundary, T rightBoundary) where T : IComparable
        {
            ArgumentHelper.Instance.CheckNull(rightBoundary, "rightBoundary");

            if(value.IsNull())
            {
                value = leftBoundary;
            }
            else
            {
                var isInOrder = leftBoundary.CompareTo(rightBoundary) <= 0;
                var small = isInOrder ? leftBoundary : rightBoundary;
                var big = isInOrder ? rightBoundary : leftBoundary;
                if(value.CompareTo(small) < 0)
                {
                    value = small;
                }
                else if(value.CompareTo(big) > 0)
                {
                    value = big;
                }
            }

            return value;
        }

        public static T Restrict<T>(this T value, T restrictionValue, RangeRestriction restrictionType)
            where T : IComparable
        {
            switch(restrictionType)
            {
                case RangeRestriction.Min:
                    return (value.CompareTo(restrictionValue) < 0) ? restrictionValue : value;
                case RangeRestriction.Max:
                    return (value.CompareTo(restrictionValue) > 0) ? restrictionValue : value;
                default:
                    throw new ArgumentOutOfRangeException("restrictionType");
            }
        }
    }

    public enum RangeRestriction
    {
        Min,
        Max
    }
}